# -*- coding: utf-8 -*-

from odoo import http
from odoo.http import request
from .main import api_response, validate_token
import logging

_logger = logging.getLogger(__name__)


class AuthController(http.Controller):
    
    # 微信小程序配置
    WECHAT_APPID = 'wxfeaa1ee058fcf034'
    WECHAT_SECRET = '1a0e8a89cbccb51dba7e9cbae41cbad7'
    
    # access_token缓存（类变量）
    _access_token_cache = None
    _access_token_expires = 0

    def _get_wechat_access_token(self):
        """获取微信access_token（带缓存）"""
        import time
        import requests
        
        # 检查缓存是否有效（提前5分钟过期）
        if self._access_token_cache and time.time() < (self._access_token_expires - 300):
            _logger.info('🔑 使用缓存的access_token')
            return self._access_token_cache
        
        try:
            # 获取新的access_token
            url = 'https://api.weixin.qq.com/cgi-bin/token'
            params = {
                'grant_type': 'client_credential',
                'appid': self.WECHAT_APPID,
                'secret': self.WECHAT_SECRET
            }
            
            _logger.info('🔑 获取微信access_token...')
            response = requests.get(url, params=params, timeout=10)
            result = response.json()
            
            if 'access_token' in result:
                # 缓存access_token（有效期7200秒=2小时）
                AuthController._access_token_cache = result['access_token']
                AuthController._access_token_expires = time.time() + result.get('expires_in', 7200)
                _logger.info(f'✅ 获取access_token成功，有效期{result.get("expires_in")}秒')
                return result['access_token']
            else:
                _logger.error(f'❌ 获取access_token失败: {result.get("errmsg")}')
                return None
                
        except Exception as e:
            _logger.error(f'❌ 获取access_token异常: {str(e)}')
            return None

    def _get_wechat_openid(self, code):
        """调用微信code2Session接口获取真实openid"""
        if not code or code == '':
            _logger.warning('⚠️ Code为空，无法获取openid')
            return None
        
        try:
            import requests
            
            # 微信code2Session接口
            url = 'https://api.weixin.qq.com/sns/jscode2session'
            params = {
                'appid': self.WECHAT_APPID,
                'secret': self.WECHAT_SECRET,
                'js_code': code,
                'grant_type': 'authorization_code'
            }
            
            _logger.info(f'🔑 调用微信code2Session: code={code[:10]}...')
            
            response = requests.get(url, params=params, timeout=10)
            result = response.json()
            
            _logger.info(f'📥 微信返回: {result}')
            
            if 'openid' in result:
                _logger.info(f'✅ 获取openid成功: {result["openid"]}')
                return result['openid']
            elif 'errcode' in result:
                _logger.error(f'❌ 微信API错误: {result.get("errmsg")}')
                return None
            else:
                _logger.error('❌ 微信返回数据格式异常')
                return None
                
        except Exception as e:
            _logger.error(f'❌ 调用微信API失败: {str(e)}')
            # 开发环境回退方案：使用code模拟openid
            _logger.warning(f'⚠️ 使用模拟openid: wx_{code[:10]}')
            return f'wx_{code}'

    @http.route('/api/v1/auth/login', type='json', auth='public', methods=['POST'], csrf=False, cors='*')
    def login(self, **kwargs):
        """微信登录 - 所有用户都可以登录"""
        try:
            # Odoo type='json' 路由：直接读取原始请求体
            import json
            body_data = request.httprequest.get_data(as_text=True)
            _logger.info(f'📥 原始请求体: {body_data}')
            data = json.loads(body_data) if body_data else {}
            code = data.get('code', '')
            user_info = data.get('user_info', {})
            
            _logger.info(f'📥 登录请求完整数据: {data}')
            _logger.info(f'📥 code={code}')
            _logger.info(f'📥 user_info完整数据: {user_info}')
            _logger.info(f'🏷️ nickName: {user_info.get("nickName")}')
            _logger.info(f'🖼️ avatarUrl: {user_info.get("avatarUrl")}')
            
            # 调用微信API获取真实openid
            openid = self._get_wechat_openid(code)
            
            if not openid:
                _logger.error('❌ 获取openid失败')
                return api_response(False, message='微信登录失败，请重试')
            
            _logger.info(f'🔑 微信登录: openid={openid}, nickName={user_info.get("nickName")}')
            
            # 查找或创建用户
            user = request.env['wechat.user'].sudo().search([('openid', '=', openid)], limit=1)
            
            if not user:
                # 创建新用户，默认为普通用户
                user = request.env['wechat.user'].sudo().create({
                    'openid': openid,
                    'name': user_info.get('nickName', '微信用户'),
                    'avatar_url': user_info.get('avatarUrl', ''),
                    'gender': str(user_info.get('gender', 0)),
                    'city': user_info.get('city', ''),
                    'province': user_info.get('province', ''),
                    'country': user_info.get('country', ''),
                    'role': 'user',  # 默认为普通用户
                })
                _logger.info(f'创建新用户: id={user.id}, name={user.name}')
            else:
                # 更新用户信息
                old_name = user.name
                old_avatar = user.avatar_url
                
                update_vals = {
                    'name': user_info.get('nickName', user.name),
                    'avatar_url': user_info.get('avatarUrl', user.avatar_url),
                }
                
                _logger.info(f'🔄 准备更新用户: id={user.id}')
                _logger.info(f'🔄 旧数据: name={old_name}, avatar={old_avatar}')
                _logger.info(f'🔄 新数据: name={update_vals["name"]}, avatar={update_vals["avatar_url"]}')
                
                user.sudo().write(update_vals)
                
                # 重新读取用户数据以确保获取最新值
                user = request.env['wechat.user'].sudo().browse(user.id)
                
                _logger.info(f'✅ 用户登录: id={user.id}, name={user.name}, avatar={user.avatar_url}, role={user.role}')
            
            # 生成令牌
            token = user.generate_token()
            
            return api_response(True, {
                'token': token,
                'userInfo': {
                    'id': user.id,
                    'name': user.name,
                    'phone': user.phone,
                    'email': user.email,
                    'avatar': user.avatar_url,
                    'role': user.role,
                    'is_admin': user.role == 'admin',  # 全局管理员
                }
            }, '登录成功')
            
        except Exception as e:
            _logger.error(f'登录失败: {str(e)}')
            return api_response(False, message=f'登录失败: {str(e)}')

    @http.route('/api/v1/auth/bind-phone', type='json', auth='public', methods=['POST'], csrf=False, cors='*')
    @validate_token
    def bind_phone(self, encrypted_data=None, iv=None, **kwargs):
        """绑定手机号"""
        try:
            if encrypted_data is None:
                encrypted_data = ''
            if iv is None:
                iv = ''
            
            # 这里应该解密微信加密的手机号数据
            # 简化处理
            phone = '13800138000'  # 实际应该从解密数据中获取
            
            request.wechat_user.sudo().write({
                'phone': phone
            })
            
            return api_response(True, {'phone': phone}, '绑定成功')
            
        except Exception as e:
            _logger.error(f'绑定手机号失败: {str(e)}')
            return api_response(False, message=f'绑定失败: {str(e)}')

    @http.route('/api/v1/user/validate', type='http', auth='public', methods=['GET'], csrf=False, cors='*')
    def validate_user(self, **kwargs):
        """验证用户令牌"""
        # 手动验证Token（type='http'需要手动验证）
        token = request.httprequest.headers.get('Authorization', '').replace('Bearer ', '')
        _logger.info(f'🔍 验证Token请求: token={token[:20] if token else "无"}...')
        
        if not token:
            _logger.warning('⚠️ 未提供Token')
            return request.make_json_response(api_response(False, message='未提供访问令牌', code=401))
        
        user = request.env['wechat.user'].sudo().search([('token', '=', token)], limit=1)
        
        if not user or not user.check_token(token):
            _logger.warning(f'⚠️ Token无效或过期: {token[:20]}...')
            return request.make_json_response(api_response(False, message='令牌无效或已过期', code=401))
        
        _logger.info(f'💚 Token验证成功: 用户={user.name}, ID={user.id}, role={user.role}')
        return request.make_json_response(api_response(True, {
            'valid': True, 
            'user_id': user.id, 
            'user_name': user.name,
            'role': user.role,
            'is_admin': user.role == 'admin'
        }, '令牌有效'))

    @http.route('/api/v1/user/info', type='http', auth='public', methods=['GET', 'PUT'], csrf=False, cors='*')
    def user_info(self, **kwargs):
        """获取/更新用户信息"""
        try:
            # 手动验证Token（type='http'需要手动验证）
            token = request.httprequest.headers.get('Authorization', '').replace('Bearer ', '')
            _logger.info(f'🔍 {request.httprequest.method} /user/info: token={token[:20] if token else "无"}...')
            
            if not token:
                _logger.warning('⚠️ 未提供Token')
                return request.make_json_response(api_response(False, message='请先登录', code=401))
            
            user = request.env['wechat.user'].sudo().search([('token', '=', token)], limit=1)
            
            if not user or not user.check_token(token):
                _logger.warning(f'⚠️ Token无效: {token[:20]}...')
                return request.make_json_response(api_response(False, message='登录已过期，请重新登录', code=401))
            
            request.wechat_user = user
            _logger.info(f'💚 Token验证成功: 用户={user.name}')
            
            if request.httprequest.method == 'GET':
                _logger.info(f'✅ 返回用户信息: name={user.name}, role={user.role}')
                
                return request.make_json_response(api_response(True, {
                    'id': user.id,
                    'name': user.name,
                    'phone': user.phone,
                    'email': user.email,
                    'avatar': user.avatar_url,
                    'role': user.role,
                    'is_admin': user.role == 'admin',
                }))
            
            elif request.httprequest.method == 'PUT':
                # 从Body读取数据
                import json
                body_data = request.httprequest.get_data(as_text=True)
                data = json.loads(body_data) if body_data else {}
                
                _logger.info(f'📝 更新用户信息: data={data}')
                
                update_vals = {}
                
                if 'name' in data:
                    update_vals['name'] = data['name']
                if 'phone' in data:
                    update_vals['phone'] = data['phone']
                if 'email' in data:
                    update_vals['email'] = data['email']
                
                user.sudo().write(update_vals)
                
                _logger.info(f'✅ 用户信息更新成功')
                
                return request.make_json_response(api_response(True, message='更新成功'))
                
        except Exception as e:
            _logger.error(f'❌ 用户信息操作失败: {str(e)}', exc_info=True)
            return request.make_json_response(api_response(False, message=f'操作失败: {str(e)}'))

    @http.route('/api/v1/upload/avatar', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
    def upload_avatar(self, **kwargs):
        """上传头像"""
        try:
            # 手动验证Token
            token = request.httprequest.headers.get('Authorization', '').replace('Bearer ', '')
            _logger.info(f'🔍 上传头像: token={token[:20] if token else "无"}...')
            
            if not token:
                _logger.warning('⚠️ 未提供Token')
                return request.make_json_response(api_response(False, message='请先登录', code=401))
            
            user = request.env['wechat.user'].sudo().search([('token', '=', token)], limit=1)
            
            if not user or not user.check_token(token):
                _logger.warning(f'⚠️ Token无效: {token[:20]}...')
                return request.make_json_response(api_response(False, message='登录已过期，请重新登录', code=401))
            
            request.wechat_user = user
            _logger.info(f'💚 Token验证成功: 用户={user.name}')
            
            # 获取上传的文件
            if 'file' not in request.httprequest.files:
                _logger.warning('⚠️ 未找到上传文件')
                return request.make_json_response(api_response(False, message='请选择要上传的文件'))
            
            file = request.httprequest.files['file']
            
            if file.filename == '':
                return request.make_json_response(api_response(False, message='文件名不能为空'))
            
            # 检查文件类型
            import os
            filename = file.filename
            file_ext = os.path.splitext(filename)[1].lower()
            allowed_exts = ['.jpg', '.jpeg', '.png', '.gif']
            
            if file_ext not in allowed_exts:
                return request.make_json_response(api_response(False, message=f'不支持的文件类型，仅支持: {", ".join(allowed_exts)}'))
            
            # 生成新的文件名（使用用户ID + 时间戳）
            import time
            new_filename = f'avatar_{user.id}_{int(time.time())}{file_ext}'
            
            # 保存文件到Odoo附件
            import base64
            file_content = file.read()
            
            attachment = request.env['ir.attachment'].sudo().create({
                'name': new_filename,
                'datas': base64.b64encode(file_content),
                'res_model': 'wechat.user',
                'res_id': user.id,
                'public': True,
                'type': 'binary',
            })
            
            # 生成访问URL（使用固定的外部域名）
            avatar_url = f'https://naturedao.tech/web/content/{attachment.id}?download=true'
            
            # 更新用户头像
            user.sudo().write({'avatar_url': avatar_url})
            
            _logger.info(f'✅ 头像上传成功: url={avatar_url}')
            
            return request.make_json_response(api_response(True, {
                'avatar_url': avatar_url,
                'attachment_id': attachment.id
            }, '上传成功'))
            
        except Exception as e:
            _logger.error(f'❌ 上传头像失败: {str(e)}', exc_info=True)
            return request.make_json_response(api_response(False, message=f'上传失败: {str(e)}'))
    
    @http.route('/api/v1/upload', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
    def upload_file(self, **kwargs):
        """通用文件上传接口"""
        try:
            # 验证Token
            token = request.httprequest.headers.get('Authorization', '').replace('Bearer ', '')
            _logger.info(f'📁 POST /upload: type={kwargs.get("type", "未知")}')
            
            if not token:
                return request.make_json_response(api_response(False, message='请先登录', code=401))
            
            user = request.env['wechat.user'].sudo().search([('token', '=', token)], limit=1)
            
            if not user or not user.check_token(token):
                return request.make_json_response(api_response(False, message='登录已过期', code=401))
            
            # 获取上传的文件
            if 'file' not in request.httprequest.files:
                return request.make_json_response(api_response(False, message='请选择要上传的文件'))
            
            file = request.httprequest.files['file']
            
            if file.filename == '':
                return request.make_json_response(api_response(False, message='文件名不能为空'))
            
            # 检查文件类型
            import os
            filename = file.filename
            file_ext = os.path.splitext(filename)[1].lower()
            allowed_exts = ['.jpg', '.jpeg', '.png', '.gif', '.webp']
            
            if file_ext not in allowed_exts:
                return request.make_json_response(api_response(False, message=f'不支持的文件类型'))
            
            # 生成新的文件名
            import time
            file_type = request.httprequest.form.get('type', 'general')
            new_filename = f'{file_type}_{user.id}_{int(time.time())}{file_ext}'
            
            # 保存文件到Odoo附件
            import base64
            file_content = file.read()
            
            attachment = request.env['ir.attachment'].sudo().create({
                'name': new_filename,
                'datas': base64.b64encode(file_content),
                'res_model': 'wechat.user',
                'res_id': user.id,
                'public': True,
                'type': 'binary',
            })
            
            # 使用固定的外部域名
            file_url = f'https://naturedao.tech/web/content/{attachment.id}?download=true'
            
            _logger.info(f'✅ 文件上传成功: type={file_type}, url={file_url}')
            
            return request.make_json_response(api_response(True, {
                'url': file_url,
                'attachment_id': attachment.id
            }, '上传成功'))
            
        except Exception as e:
            _logger.error(f'❌ 文件上传失败: {str(e)}', exc_info=True)
            return request.make_json_response(api_response(False, message=f'上传失败: {str(e)}'))

